﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Client.TopLevel
{
    #region Top-level Objects

    public class TLWorkTime
    {
        public DateTime TimeIn  { get; set; }
        public DateTime TimeOut { get; set; }

        public TLWorkTime()
        {
            TimeIn  = DateTime.Now;
            TimeOut = DateTime.Now;
        }

        public TLWorkTime(DateTime timeIn, DateTime timeOut)
        {
            TimeIn  = timeIn;
            TimeOut = timeOut;
        }

        internal TLWorkTime(TimeTable timeTable)
        {
            new TLWorkTime(Convert.ToDateTime(timeTable.TimeIn), Convert.ToDateTime(timeTable.TimeOut));
        }
    }

    public class TLEmployee
    {
        public int    Id            { get; set; }
        public string Name          { get; set; }
        public string Login         { get; set; }
        public string Password      { get; set; }
        public int    PositionId    { get; set; }
        public int    BankAccountId { get; set; }
        public byte   Role          { get; set; }

        public TLEmployee()
        {
            Id              = Defaults.DEFAULT_INT;
            Name            = Defaults.DEFAULT_STR;
            Login           = Defaults.DEFAULT_STR;
            Password        = Defaults.DEFAULT_STR;
            Role            = Defaults.DEFAULT_ROLE;
            BankAccountId   = Defaults.DEFAULT_INT;
            PositionId      = Defaults.DEFAULT_INT;
        }

        public TLEmployee(TLEmployee employee)
        {
            Id              = employee.Id;
            Name            = employee.Name;
            Login           = employee.Login;
            Password        = employee.Password;
            Role            = employee.Role;
            BankAccountId   = employee.BankAccountId;
            PositionId      = employee.PositionId;
        }

        public TLEmployee(int id, string name, string login, string password, byte role, int bankAccountId, int positionId)
        {
            Id              = id;
            Name            = name;
            Login           = login;
            Password        = password;
            Role            = role;
            BankAccountId   = bankAccountId;
            PositionId      = positionId;
        }

        internal TLEmployee(Employee employee)
        {
            Id              = employee.Id;
            Name            = employee.Name;
            Login           = employee.Login;
            Password        = employee.Password;
            Role            = employee.Role;
            BankAccountId   = employee.BankAccountId;
            PositionId      = employee.PositionId;
        }

        internal Employee ToEmployee()
        {
            return new Employee(Id, Name, Login, Password, Role, BankAccountId, PositionId);
        }
    }

    public class TLReport
    {
        public TLEmployee       Employee { get; set; }
        public List<TLWorkTime> Time     { get; set; }

        public TLReport()
        {
            Employee = new TLEmployee();
            Time     = new List<TLWorkTime>();
        }

        public TLReport(TLEmployee employee, IEnumerable<TLWorkTime> workTime)
        {
            Employee = new TLEmployee(employee);
            Time     = new List<TLWorkTime>(workTime);
        }
    }

    public class TLTask
    {
        public int        Id              { get; set; }
        public string     Title           { get; set; }
        public DateTime   StartTime       { get; set; }
        public DateTime   EndTime         { get; set; }
        public DateTime   EstimationTime  { get; set; }
        public int        Cost            { get; set; }
        public int        Penalty         { get; set; }
        public int        EmployeeId      { get; set; }

        public TLTask()
        {
            Id              = Defaults.DEFAULT_INT;
            Title           = Defaults.DEFAULT_STR;
            StartTime       = DateTime.Now;
            EndTime         = DateTime.Now;
            EstimationTime  = DateTime.Now;
            Cost            = Defaults.DEFAULT_INT;
            Penalty         = Defaults.DEFAULT_INT;
            EmployeeId      = Defaults.DEFAULT_INT;
        }

        public TLTask(int id, string title, DateTime stTime, DateTime endTime, DateTime estTime, int cost, int penalty, int employeeId)
        {
            Id              = id;
            Title           = title;
            StartTime       = stTime;
            EndTime         = endTime;
            EstimationTime  = estTime;
            Cost            = cost;
            Penalty         = penalty;
            EmployeeId      = employeeId;
        }

        internal TLTask(Task task)
        {
            Id              = task.Id;
            Title           = task.Title;
            StartTime       = Convert.ToDateTime(task.StartTime);
            EndTime         = Convert.ToDateTime(task.EndTime);
            EstimationTime  = Convert.ToDateTime(task.EstimationTime);
            Cost            = task.Cost;
            Penalty         = task.Penalty;
            EmployeeId      = task.EmployeeId;
        }

        internal Task ToTask()
        {
            return new Task(Id, Title, StartTime.ToString(), EndTime.ToString(), EstimationTime.ToString(), Cost, Penalty, EmployeeId);
        }
    }

    #endregion

    #region Systems

    public class IdentificationSys : IIdentificationSys
    {
        private RepositoryManager RepositoryMan;

        public IdentificationSys(string login, string password)
        {
            RepositoryMan = RepositoryManager.GetRepositoryManager(login, password);
        }

        public RepositoryManager GetRepositoryManager()
        {
            return RepositoryMan;
        }
    }

    public class LoginSys : ILoginSys
    {
        private IIdentificationSys identificationSys;

        public LoginSys(string login, string password)
        {
            identificationSys = new IdentificationSys(login, password);
        }

        public bool LogIn()
        {
            try
            {
                return identificationSys.GetRepositoryManager().TimeTableRepository.LogIn();
            }
            catch { }

            return false;
        }

        public bool LogOut()
        {
            try
            {
                return identificationSys.GetRepositoryManager().TimeTableRepository.LogOut();
            }
            catch { }

            return false;
        }
    }

    public class PersonnelSys : IPersonnelSys
    {
        private IIdentificationSys identificationSys;

        public PersonnelSys(string login, string password)
        {
            identificationSys = new IdentificationSys(login, password);
        }
        
        public TLEmployee GetEmployee()
        {
            try
            {
                return new TLEmployee(identificationSys.GetRepositoryManager().EmployeeRepository.GetData());
            }
            catch { }

            return null;
        }

        public bool FinishTash(TLTask task)
        {
            try
            {
                return identificationSys.GetRepositoryManager().TaskRepository.FinishTask(task.ToTask());
            }
            catch { }

            return false;
        }

        public bool AddEmployee(TLEmployee employee)
        {
            try
            {
                return identificationSys.GetRepositoryManager().EmployeeRepository.AddEmployee(employee.ToEmployee());
            }
            catch { }

            return false;
        }

        public bool EditEmployee(TLEmployee oldEmployee, TLEmployee newEmployee)
        {
            try
            {
                return identificationSys.GetRepositoryManager().EmployeeRepository.EditEmployee(oldEmployee.ToEmployee(), newEmployee.ToEmployee());
            }
            catch { }

            return false;
        }

        public bool DeleteEmployee(TLEmployee employee)
        {
            try
            {
                return identificationSys.GetRepositoryManager().EmployeeRepository.DeleteEmployee(employee.ToEmployee());
            }
            catch { }

            return false;
        }

        public IEnumerable<TLEmployee> GetAll()
        {
            try
            {
                List<TLEmployee> result = new List<TLEmployee>();

                foreach (Employee employee in identificationSys.GetRepositoryManager().EmployeeRepository.GetAll())
                {
                    result.Add(new TLEmployee(employee));
                }

                return result;
            }
            catch { }

            return null;
        }

        public bool AddTask(TLTask task)
        {
            try
            {
                return identificationSys.GetRepositoryManager().TaskRepository.AddTask(task.ToTask());
            }
            catch { }

            return false;
        }

        public bool DeleteTask(TLTask task)
        {
            try
            {
                return identificationSys.GetRepositoryManager().TaskRepository.DeleteTask(task.ToTask());
            }
            catch { }

            return false;
        }

        public bool EditTask(TLTask oldTask, TLTask newTask)
        {
            try
            {
                return identificationSys.GetRepositoryManager().TaskRepository.EditTask(oldTask.ToTask(), newTask.ToTask());
            }
            catch { }

            return false;
        }

        public bool CloseTask(TLTask task)
        {
            // TODO:

            return false;
        }

        public IEnumerable<TLTask> GetAllTasks()
        {
            try
            {
                List<TLTask> result = new List<TLTask>();

                foreach (Task task in identificationSys.GetRepositoryManager().TaskRepository.GetAll())
                {
                    result.Add(new TLTask(task));
                }

                return result;
            }
            catch { }

            return null;
        }
    }

    public class ReportSys : IReportSys
    {
        private IIdentificationSys identificationSys;

        public ReportSys(string login, string password)
        {
            identificationSys = new IdentificationSys(login, password);
        }

        public TLReport Get()
        {
            // TODO:

            return null;
        }

        public IEnumerable<TLReport> GetAll()
        {
            // TODO:

            return null;
        }        
    }

    public class SalarySys : ISalarySys
    {
        private IIdentificationSys identificationSys;

        public SalarySys(string login, string password)
        {
            identificationSys = new IdentificationSys(login, password);
        }

        public int Get(DateTime startTime, DateTime endTime)
        {
            // TODO:

            return 0;
        }

        public bool Pay(TLEmployee user, DateTime startTime, DateTime endTime)
        {
            // TODO:

            return false;
        }

        public bool PayAll(DateTime startTime, DateTime endTime)
        {
            // TODO:

            return false;
        }
    }

    #endregion
}
